<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AI大模型二次开发平台 - Web界面</title>
    <!-- 引入Tailwind CSS -->
    <script src="https://cdn.tailwindcss.com"></script>
    <!-- 引入Font Awesome -->
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    
    <!-- 配置Tailwind CSS主题 -->
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#3B82F6',
                        secondary: '#10B981',
                        accent: '#8B5CF6',
                        dark: '#1F2937',
                        light: '#F3F4F6'
                    },
                    fontFamily: {
                        sans: ['Inter', 'system-ui', 'sans-serif'],
                    },
                }
            }
        }
    </script>
    
    <!-- 自定义工具类 -->
    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            .scrollbar-hide {
                -ms-overflow-style: none;
                scrollbar-width: none;
            }
            .scrollbar-hide::-webkit-scrollbar {
                display: none;
            }
            .animate-pulse-slow {
                animation: pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite;
            }
        }
    </style>
</head>
<body class="bg-gray-50 min-h-screen">
    <!-- 导航栏 -->
    <nav class="bg-white shadow-md">
        <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
            <div class="flex justify-between h-16">
                <div class="flex items-center">
                    <div class="flex-shrink-0 flex items-center">
                        <i class="fa fa-brain text-primary text-2xl mr-2"></i>
                        <span class="font-bold text-xl text-gray-800">AI大模型二次开发平台</span>
                    </div>
                </div>
                <div class="flex items-center">
                    <button id="theme-toggle" class="p-2 rounded-full text-gray-500 hover:text-primary hover:bg-gray-100 focus:outline-none">
                        <i class="fa fa-moon-o"></i>
                    </button>
                </div>
            </div>
        </div>
    </nav>

    <!-- 主内容区 -->
    <main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
        <!-- 功能选项卡 -->
        <div class="mb-6">
            <div class="border-b border-gray-200">
                <nav class="flex -mb-px space-x-8">
                    <button id="tab-chat" class="px-1 py-4 border-b-2 border-primary text-primary font-medium">
                        <i class="fa fa-comments mr-2"></i>聊天对话
                    </button>
                    <button id="tab-rag" class="px-1 py-4 border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 font-medium">
                        <i class="fa fa-search mr-2"></i>RAG检索
                    </button>
                    <button id="tab-models" class="px-1 py-4 border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 font-medium">
                        <i class="fa fa-cubes mr-2"></i>模型管理
                    </button>
                </nav>
            </div>
        </div>

        <!-- 聊天对话面板 -->
        <div id="panel-chat" class="bg-white rounded-lg shadow-md overflow-hidden">
            <!-- 模型选择和控制 -->
            <div class="p-4 border-b border-gray-200 bg-gray-50">
                <div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
                    <div class="flex items-center gap-4">
                        <div>
                            <label for="model-select" class="block text-sm font-medium text-gray-700 mb-1">选择模型</label>
                            <select id="model-select" class="block w-full rounded-md border-gray-300 shadow-sm focus:border-primary focus:ring focus:ring-primary focus:ring-opacity-50 px-3 py-2 border">
                                <option value="Qwen2.5-7B-Instruct">Qwen2.5-7B-Instruct (默认)</option>
                            </select>
                        </div>
                        <div>
                            <label for="temperature" class="block text-sm font-medium text-gray-700 mb-1">生成温度</label>
                            <input type="range" id="temperature" min="0" max="1" step="0.1" value="0.7" 
                                class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer">
                            <div class="text-xs text-gray-500 text-center">0.7</div>
                        </div>
                        <div>
                            <label for="max-tokens" class="block text-sm font-medium text-gray-700 mb-1">最大Token</label>
                            <select id="max-tokens" class="block w-full rounded-md border-gray-300 shadow-sm focus:border-primary focus:ring focus:ring-primary focus:ring-opacity-50 px-3 py-2 border">
                                <option value="512">512</option>
                                <option value="1024" selected>1024</option>
                                <option value="2048">2048</option>
                                <option value="4096">4096</option>
                            </select>
                        </div>
                    </div>
                    <div class="flex gap-2">
                        <button id="clear-chat" class="px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none">
                            <i class="fa fa-trash mr-1"></i>清空对话
                        </button>
                        <button id="load-models" class="px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none">
                            <i class="fa fa-refresh mr-1"></i>加载模型
                        </button>
                    </div>
                </div>
            </div>

            <!-- 聊天内容 -->
            <div id="chat-messages" class="p-4 h-[400px] overflow-y-auto scrollbar-hide space-y-4">
                <!-- 欢迎消息 -->
                <div class="flex items-start gap-3">
                    <div class="flex-shrink-0 w-8 h-8 rounded-full bg-primary flex items-center justify-center text-white">
                        <i class="fa fa-robot"></i>
                    </div>
                    <div class="flex-1">
                        <div class="bg-gray-100 rounded-lg px-4 py-3">
                            <p class="text-gray-800">欢迎使用AI大模型二次开发平台！我是你的AI助手，有什么可以帮助你的吗？</p>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 输入区域 -->
            <div class="p-4 border-t border-gray-200">
                <div class="flex gap-2">
                    <textarea id="user-input" rows="3" placeholder="请输入你的问题或指令..." 
                        class="flex-1 rounded-md border-gray-300 shadow-sm focus:border-primary focus:ring focus:ring-primary focus:ring-opacity-50 px-4 py-2 border resize-none"></textarea>
                    <button id="send-message" class="px-6 py-2 bg-primary text-white rounded-md shadow-sm hover:bg-primary/90 focus:outline-none flex-shrink-0">
                        <i class="fa fa-paper-plane"></i>
                    </button>
                </div>
            </div>
        </div>

        <!-- RAG检索面板 -->
        <div id="panel-rag" class="bg-white rounded-lg shadow-md overflow-hidden hidden">
            <div class="p-6">
                <h2 class="text-xl font-semibold text-gray-900 mb-4">知识库检索 (RAG)</h2>
                <div class="space-y-4">
                    <div>
                        <label for="rag-query" class="block text-sm font-medium text-gray-700 mb-1">查询问题</label>
                        <textarea id="rag-query" rows="3" placeholder="请输入你想在知识库中检索的问题..." 
                            class="w-full rounded-md border-gray-300 shadow-sm focus:border-primary focus:ring focus:ring-primary focus:ring-opacity-50 px-4 py-2 border resize-none"></textarea>
                    </div>
                    <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
                        <div>
                            <label for="rag-model" class="block text-sm font-medium text-gray-700 mb-1">选择模型</label>
                            <select id="rag-model" class="w-full rounded-md border-gray-300 shadow-sm focus:border-primary focus:ring focus:ring-primary focus:ring-opacity-50 px-3 py-2 border">
                                <option value="Qwen2.5-7B-Instruct">Qwen2.5-7B-Instruct (默认)</option>
                            </select>
                        </div>
                        <div>
                            <label for="rag-topk" class="block text-sm font-medium text-gray-700 mb-1">检索文档数</label>
                            <select id="rag-topk" class="w-full rounded-md border-gray-300 shadow-sm focus:border-primary focus:ring focus:ring-primary focus:ring-opacity-50 px-3 py-2 border">
                                <option value="3">3</option>
                                <option value="5" selected>5</option>
                                <option value="10">10</option>
                            </select>
                        </div>
                        <div>
                            <label for="rag-options" class="block text-sm font-medium text-gray-700 mb-1">检索选项</label>
                            <div class="flex items-center space-x-2">
                                <label class="inline-flex items-center">
                                    <input type="checkbox" id="use-rag" class="rounded text-primary focus:ring-primary" checked>
                                    <span class="ml-2 text-sm text-gray-700">使用RAG</span>
                                </label>
                            </div>
                        </div>
                    </div>
                    <div class="flex justify-between items-center">
                        <button id="upload-document" class="px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none">
                            <i class="fa fa-upload mr-1"></i>上传文档
                        </button>
                        <button id="run-rag-query" class="px-6 py-2 bg-accent text-white rounded-md shadow-sm hover:bg-accent/90 focus:outline-none">
                            <i class="fa fa-search mr-1"></i>执行检索
                        </button>
                    </div>
                </div>
                
                <!-- RAG结果展示 -->
                <div id="rag-results" class="mt-6 hidden">
                    <h3 class="text-lg font-semibold text-gray-900 mb-3">检索结果</h3>
                    
                    <!-- 回答部分 -->
                    <div class="mb-4 p-4 bg-blue-50 rounded-lg">
                        <h4 class="text-sm font-medium text-blue-700 mb-2">AI回答</h4>
                        <div id="rag-answer" class="text-gray-800"></div>
                    </div>
                    
                    <!-- 相关文档部分 -->
                    <div>
                        <h4 class="text-sm font-medium text-gray-700 mb-2">相关文档</h4>
                        <div id="rag-sources" class="space-y-3 max-h-[300px] overflow-y-auto scrollbar-hide"></div>
                    </div>
                </div>
            </div>
        </div>

        <!-- 模型管理面板 -->
        <div id="panel-models" class="bg-white rounded-lg shadow-md overflow-hidden hidden">
            <div class="p-6">
                <h2 class="text-xl font-semibold text-gray-900 mb-4">模型管理</h2>
                
                <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                    <!-- 已加载模型 -->
                    <div>
                        <h3 class="text-lg font-medium text-gray-900 mb-3">已加载模型</h3>
                        <div id="loaded-models" class="space-y-2">
                            <div class="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
                                <div class="flex items-center gap-2">
                                    <div class="w-2 h-2 rounded-full bg-green-500"></div>
                                    <span class="text-gray-800">加载中...</span>
                                </div>
                                <button class="text-gray-500 hover:text-red-500"><i class="fa fa-times"></i></button>
                            </div>
                        </div>
                    </div>
                    
                    <!-- 加载新模型 -->
                    <div>
                        <h3 class="text-lg font-medium text-gray-900 mb-3">加载新模型</h3>
                        <div class="space-y-4">
                            <div>
                                <label for="new-model-name" class="block text-sm font-medium text-gray-700 mb-1">模型名称/路径</label>
                                <input type="text" id="new-model-name" class="w-full rounded-md border-gray-300 shadow-sm focus:border-primary focus:ring focus:ring-primary focus:ring-opacity-50 px-4 py-2 border" 
                                    placeholder="如: Qwen/Qwen2.5-7B-Instruct">
                            </div>
                            <div class="flex items-center space-x-2">
                                <label class="inline-flex items-center">
                                    <input type="checkbox" id="use-quantization" class="rounded text-primary focus:ring-primary">
                                    <span class="ml-2 text-sm text-gray-700">使用量化</span>
                                </label>
                            </div>
                            <button id="load-new-model" class="w-full px-4 py-2 bg-primary text-white rounded-md shadow-sm hover:bg-primary/90 focus:outline-none">
                                <i class="fa fa-download mr-1"></i>加载模型
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- 状态提示 -->
        <div id="status-toast" class="fixed bottom-4 right-4 px-4 py-3 rounded-md shadow-lg bg-white border-l-4 border-primary transform transition-all duration-300 translate-y-16 opacity-0">
            <div class="flex items-center gap-2">
                <i id="status-icon" class="fa fa-info-circle text-primary"></i>
                <p id="status-message" class="text-sm text-gray-700"></p>
            </div>
        </div>
    </main>

    <!-- 页脚 -->
    <footer class="bg-white border-t border-gray-200 mt-8">
        <div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
            <p class="text-center text-sm text-gray-500">© 2024 AI大模型二次开发平台 - 所有权利保留</p>
        </div>
    </footer>

    <!-- JavaScript -->
    <script>
        // API基础URL
        const API_BASE_URL = 'http://localhost:8000';
        
        // DOM元素
        const tabChat = document.getElementById('tab-chat');
        const tabRag = document.getElementById('tab-rag');
        const tabModels = document.getElementById('tab-models');
        const panelChat = document.getElementById('panel-chat');
        const panelRag = document.getElementById('panel-rag');
        const panelModels = document.getElementById('panel-models');
        const chatMessages = document.getElementById('chat-messages');
        const userInput = document.getElementById('user-input');
        const sendMessage = document.getElementById('send-message');
        const clearChat = document.getElementById('clear-chat');
        const modelSelect = document.getElementById('model-select');
        const temperature = document.getElementById('temperature');
        const maxTokens = document.getElementById('max-tokens');
        const loadModels = document.getElementById('load-models');
        const ragQuery = document.getElementById('rag-query');
        const ragModel = document.getElementById('rag-model');
        const ragTopk = document.getElementById('rag-topk');
        const useRag = document.getElementById('use-rag');
        const runRagQuery = document.getElementById('run-rag-query');
        const ragResults = document.getElementById('rag-results');
        const ragAnswer = document.getElementById('rag-answer');
        const ragSources = document.getElementById('rag-sources');
        const loadedModels = document.getElementById('loaded-models');
        const newModelName = document.getElementById('new-model-name');
        const useQuantization = document.getElementById('use-quantization');
        const loadNewModel = document.getElementById('load-new-model');
        const statusToast = document.getElementById('status-toast');
        const statusIcon = document.getElementById('status-icon');
        const statusMessage = document.getElementById('status-message');
        const themeToggle = document.getElementById('theme-toggle');
        const uploadDocument = document.getElementById('upload-document');
        
        // 初始化
        function init() {
            // 注册事件监听器
            registerEventListeners();
            
            // 加载模型列表
            loadModelList();
            
            // 初始化温度显示
            updateTemperatureDisplay();
        }
        
        // 注册事件监听器
        function registerEventListeners() {
            // 选项卡切换
            tabChat.addEventListener('click', () => switchTab('chat'));
            tabRag.addEventListener('click', () => switchTab('rag'));
            tabModels.addEventListener('click', () => switchTab('models'));
            
            // 聊天功能
            sendMessage.addEventListener('click', sendUserMessage);
            userInput.addEventListener('keydown', (e) => {
                if (e.key === 'Enter' && !e.shiftKey) {
                    e.preventDefault();
                    sendUserMessage();
                }
            });
            clearChat.addEventListener('click', clearChatMessages);
            
            // 温度调节
            temperature.addEventListener('input', updateTemperatureDisplay);
            
            // 加载模型列表
            loadModels.addEventListener('click', loadModelList);
            
            // RAG功能
            runRagQuery.addEventListener('click', executeRagQuery);
            
            // 模型管理
            loadNewModel.addEventListener('click', handleLoadNewModel);
            
            // 主题切换
            themeToggle.addEventListener('click', toggleTheme);
            
            // 上传文档
            uploadDocument.addEventListener('click', handleUploadDocument);
        }
        
        // 切换选项卡
        function switchTab(tabName) {
            // 重置所有选项卡和面板
            [tabChat, tabRag, tabModels].forEach(tab => {
                tab.classList.remove('border-primary', 'text-primary');
                tab.classList.add('border-transparent', 'text-gray-500', 'hover:text-gray-700', 'hover:border-gray-300');
            });
            [panelChat, panelRag, panelModels].forEach(panel => panel.classList.add('hidden'));
            
            // 激活选中的选项卡和面板
            if (tabName === 'chat') {
                tabChat.classList.remove('border-transparent', 'text-gray-500', 'hover:text-gray-700', 'hover:border-gray-300');
                tabChat.classList.add('border-primary', 'text-primary');
                panelChat.classList.remove('hidden');
            } else if (tabName === 'rag') {
                tabRag.classList.remove('border-transparent', 'text-gray-500', 'hover:text-gray-700', 'hover:border-gray-300');
                tabRag.classList.add('border-primary', 'text-primary');
                panelRag.classList.remove('hidden');
            } else if (tabName === 'models') {
                tabModels.classList.remove('border-transparent', 'text-gray-500', 'hover:text-gray-700', 'hover:border-gray-300');
                tabModels.classList.add('border-primary', 'text-primary');
                panelModels.classList.remove('hidden');
                
                // 刷新模型列表
                loadModelList(true);
            }
        }
        
        // 发送用户消息
        function sendUserMessage() {
            const message = userInput.value.trim();
            if (!message) return;
            
            // 添加用户消息到聊天界面
            addMessageToChat('user', message);
            
            // 清空输入框
            userInput.value = '';
            
            // 添加加载中消息
            const loadingMessageId = 'loading-' + Date.now();
            addLoadingMessageToChat(loadingMessageId);
            
            // 调用API发送消息
            sendChatRequest(message, loadingMessageId);
        }
        
        // 添加消息到聊天界面
        function addMessageToChat(role, content) {
            const messageDiv = document.createElement('div');
            messageDiv.className = 'flex items-start gap-3';
            
            let avatarIcon = 'fa-user';
            let avatarBg = 'bg-gray-500';
            let messageBg = 'bg-primary/10';
            let messageTextColor = 'text-gray-800';
            
            if (role === 'user') {
                avatarIcon = 'fa-user';
                avatarBg = 'bg-gray-500';
                messageDiv.classList.add('justify-end');
                messageDiv.innerHTML = `
                    <div class="flex-1 max-w-[80%]">
                        <div class="${messageBg} rounded-lg px-4 py-3 text-right">
                            <p class="${messageTextColor}">${formatMessage(content)}</p>
                        </div>
                    </div>
                    <div class="flex-shrink-0 w-8 h-8 rounded-full ${avatarBg} flex items-center justify-center text-white">
                        <i class="fa ${avatarIcon}"></i>
                    </div>
                `;
            } else {
                avatarIcon = 'fa-robot';
                avatarBg = 'bg-primary';
                messageBg = 'bg-gray-100';
                messageDiv.innerHTML = `
                    <div class="flex-shrink-0 w-8 h-8 rounded-full ${avatarBg} flex items-center justify-center text-white">
                        <i class="fa ${avatarIcon}"></i>
                    </div>
                    <div class="flex-1 max-w-[80%]">
                        <div class="${messageBg} rounded-lg px-4 py-3">
                            <p class="${messageTextColor}">${formatMessage(content)}</p>
                        </div>
                    </div>
                `;
            }
            
            chatMessages.appendChild(messageDiv);
            
            // 滚动到底部
            chatMessages.scrollTop = chatMessages.scrollHeight;
        }
        
        // 添加加载中消息
        function addLoadingMessageToChat(messageId) {
            const messageDiv = document.createElement('div');
            messageDiv.id = messageId;
            messageDiv.className = 'flex items-start gap-3';
            messageDiv.innerHTML = `
                <div class="flex-shrink-0 w-8 h-8 rounded-full bg-primary flex items-center justify-center text-white">
                    <i class="fa fa-robot"></i>
                </div>
                <div class="flex-1 max-w-[80%]">
                    <div class="bg-gray-100 rounded-lg px-4 py-3 animate-pulse-slow">
                        <div class="flex space-x-2">
                            <div class="h-2 bg-gray-300 rounded-full w-1/4"></div>
                            <div class="h-2 bg-gray-300 rounded-full w-1/6"></div>
                            <div class="h-2 bg-gray-300 rounded-full w-1/8"></div>
                        </div>
                    </div>
                </div>
            `;
            
            chatMessages.appendChild(messageDiv);
            
            // 滚动到底部
            chatMessages.scrollTop = chatMessages.scrollHeight;
        }
        
        // 格式化消息内容
        function formatMessage(content) {
            // 简单的Markdown格式化支持
            return content
                .replace(/\n/g, '<br>')
                .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
                .replace(/\*(.*?)\*/g, '<em>$1</em>')
                .replace(/`(.*?)`/g, '<code class="bg-gray-200 px-1 py-0.5 rounded text-sm font-mono">$1</code>');
        }
        
        // 清空聊天消息
        function clearChatMessages() {
            chatMessages.innerHTML = '';
            
            // 添加欢迎消息
            addMessageToChat('assistant', '欢迎使用AI大模型二次开发平台！我是你的AI助手，有什么可以帮助你的吗？');
        }
        
        // 更新温度显示
        function updateTemperatureDisplay() {
            const tempValue = temperature.value;
            const tempDisplay = temperature.parentNode.querySelector('div.text-xs');
            tempDisplay.textContent = tempValue;
        }
        
        // 显示状态提示
        function showStatus(message, type = 'info') {
            // 设置消息和图标
            statusMessage.textContent = message;
            
            // 移除所有类型的图标和边框
            statusIcon.className = 'fa';
            statusToast.classList.remove('border-primary', 'border-green-500', 'border-red-500', 'border-yellow-500');
            
            // 设置类型相关的图标和边框
            if (type === 'success') {
                statusIcon.classList.add('fa-check-circle', 'text-green-500');
                statusToast.classList.add('border-green-500');
            } else if (type === 'error') {
                statusIcon.classList.add('fa-exclamation-circle', 'text-red-500');
                statusToast.classList.add('border-red-500');
            } else if (type === 'warning') {
                statusIcon.classList.add('fa-exclamation-triangle', 'text-yellow-500');
                statusToast.classList.add('border-yellow-500');
            } else {
                statusIcon.classList.add('fa-info-circle', 'text-primary');
                statusToast.classList.add('border-primary');
            }
            
            // 显示提示
            statusToast.classList.remove('translate-y-16', 'opacity-0');
            
            // 3秒后自动隐藏
            setTimeout(() => {
                statusToast.classList.add('translate-y-16', 'opacity-0');
            }, 3000);
        }
        
        // 切换主题
        function toggleTheme() {
            const icon = themeToggle.querySelector('i');
            
            if (icon.classList.contains('fa-moon-o')) {
                icon.classList.remove('fa-moon-o');
                icon.classList.add('fa-sun-o');
                document.body.classList.add('bg-gray-900', 'text-white');
                // 这里可以添加暗黑主题的其他样式
                showStatus('已切换到暗黑模式');
            } else {
                icon.classList.remove('fa-sun-o');
                icon.classList.add('fa-moon-o');
                document.body.classList.remove('bg-gray-900', 'text-white');
                // 这里可以移除暗黑主题的其他样式
                showStatus('已切换到明亮模式');
            }
        }
        
        // API调用函数
        
        // 加载模型列表
        async function loadModelList(showInModelsPanel = false) {
            try {
                const response = await fetch(`${API_BASE_URL}/api/v1/models`);
                const data = await response.json();
                
                if (response.ok) {
                    const models = data.models;
                    
                    // 更新聊天面板的模型选择
                    modelSelect.innerHTML = '';
                    models.forEach(model => {
                        const option = document.createElement('option');
                        option.value = model;
                        option.textContent = model;
                        if (model === data.default_model) {
                            option.selected = true;
                        }
                        modelSelect.appendChild(option);
                    });
                    
                    // 更新RAG面板的模型选择
                    ragModel.innerHTML = '';
                    models.forEach(model => {
                        const option = document.createElement('option');
                        option.value = model;
                        option.textContent = model;
                        if (model === data.default_model) {
                            option.selected = true;
                        }
                        ragModel.appendChild(option);
                    });
                    
                    // 如果需要在模型面板显示
                    if (showInModelsPanel) {
                        loadedModels.innerHTML = '';
                        
                        if (models.length === 0) {
                            loadedModels.innerHTML = '<p class="text-gray-500 text-sm italic">暂无已加载的模型</p>';
                        } else {
                            models.forEach(model => {
                                const modelDiv = document.createElement('div');
                                modelDiv.className = 'flex items-center justify-between p-3 bg-gray-50 rounded-lg';
                                modelDiv.innerHTML = `
                                    <div class="flex items-center gap-2">
                                        <div class="w-2 h-2 rounded-full bg-green-500"></div>
                                        <span class="text-gray-800">${model}</span>
                                    </div>
                                    <button class="text-gray-500 hover:text-red-500 unload-model" data-model="${model}">
                                        <i class="fa fa-times"></i>
                                    </button>
                                `;
                                loadedModels.appendChild(modelDiv);
                            });
                            
                            // 为卸载按钮添加事件监听器
                            document.querySelectorAll('.unload-model').forEach(button => {
                                button.addEventListener('click', function() {
                                    const modelName = this.getAttribute('data-model');
                                    unloadModel(modelName);
                                });
                            });
                        }
                    }
                    
                    showStatus(`成功加载 ${models.length} 个模型`);
                } else {
                    showStatus('加载模型列表失败: ' + data.message, 'error');
                }
            } catch (error) {
                console.error('加载模型列表时出错:', error);
                showStatus('加载模型列表时发生错误', 'error');
            }
        }
        
        // 发送聊天请求
        async function sendChatRequest(message, loadingMessageId) {
            try {
                const response = await fetch(`${API_BASE_URL}/v1/chat/completions`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        model: modelSelect.value,
                        messages: [
                            { role: 'user', content: message }
                        ],
                        temperature: parseFloat(temperature.value),
                        max_tokens: parseInt(maxTokens.value)
                    })
                });
                
                const data = await response.json();
                
                // 移除加载中消息
                const loadingMessage = document.getElementById(loadingMessageId);
                if (loadingMessage) {
                    loadingMessage.remove();
                }
                
                if (response.ok) {
                    // 添加AI回复到聊天界面
                    const answer = data.choices[0].message.content;
                    addMessageToChat('assistant', answer);
                } else {
                    addMessageToChat('assistant', `发生错误: ${data.error?.message || '未知错误'}`);
                }
            } catch (error) {
                console.error('发送聊天请求时出错:', error);
                
                // 移除加载中消息
                const loadingMessage = document.getElementById(loadingMessageId);
                if (loadingMessage) {
                    loadingMessage.remove();
                }
                
                addMessageToChat('assistant', `发生错误: ${error.message}`);
            }
        }
        
        // 执行RAG查询
        async function executeRagQuery() {
            const query = ragQuery.value.trim();
            if (!query) {
                showStatus('请输入查询问题', 'warning');
                return;
            }
            
            // 显示加载状态
            ragResults.classList.remove('hidden');
            ragAnswer.innerHTML = '<div class="animate-pulse-slow"><div class="h-2 bg-gray-200 rounded-full w-1/4 mb-2"></div><div class="h-2 bg-gray-200 rounded-full w-1/3"></div></div>';
            ragSources.innerHTML = '<div class="animate-pulse-slow"><div class="h-2 bg-gray-200 rounded-full w-1/2 mb-2"></div><div class="h-2 bg-gray-200 rounded-full w-1/4"></div></div>';
            
            try {
                const response = await fetch(`${API_BASE_URL}/api/v1/rag/query`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        query: query,
                        model_name: ragModel.value,
                        top_k: parseInt(ragTopk.value),
                        use_rag: useRag.checked
                    })
                });
                
                const data = await response.json();
                
                if (response.ok && data.status === 'success') {
                    // 显示回答
                    ragAnswer.innerHTML = formatMessage(data.data.answer);
                    
                    // 显示来源文档
                    ragSources.innerHTML = '';
                    
                    if (data.data.sources && data.data.sources.length > 0) {
                        data.data.sources.forEach((source, index) => {
                            const sourceDiv = document.createElement('div');
                            sourceDiv.className = 'p-3 bg-gray-50 rounded-lg border-l-2 border-accent';
                            sourceDiv.innerHTML = `
                                <div class="flex justify-between items-center mb-1">
                                    <span class="text-sm font-medium text-gray-700">相关文档 #${index + 1}</span>
                                    <span class="text-xs text-gray-500">相关性: ${(source.score * 100).toFixed(1)}%</span>
                                </div>
                                <p class="text-sm text-gray-600">${formatMessage(source.text)}</p>
                                ${source.metadata ? `
                                <div class="mt-1 text-xs text-gray-500">
                                    ${Object.entries(source.metadata).map(([key, value]) => `${key}: ${value}`).join(', ')}
                                </div>
                                ` : ''}
                            `;
                            ragSources.appendChild(sourceDiv);
                        });
                    } else {
                        ragSources.innerHTML = '<p class="text-gray-500 text-sm italic">暂无相关文档</p>';
                    }
                    
                    showStatus('RAG查询完成');
                } else {
                    ragAnswer.innerHTML = `<p class="text-red-500">发生错误: ${data.message}</p>`;
                    ragSources.innerHTML = '';
                    showStatus('RAG查询失败: ' + data.message, 'error');
                }
            } catch (error) {
                console.error('执行RAG查询时出错:', error);
                ragAnswer.innerHTML = `<p class="text-red-500">发生错误: ${error.message}</p>`;
                ragSources.innerHTML = '';
                showStatus('执行RAG查询时发生错误', 'error');
            }
        }
        
        // 加载新模型
        async function handleLoadNewModel() {
            const modelName = newModelName.value.trim();
            if (!modelName) {
                showStatus('请输入模型名称或路径', 'warning');
                return;
            }
            
            // 显示加载状态
            loadNewModel.disabled = true;
            loadNewModel.innerHTML = '<i class="fa fa-spinner fa-spin mr-1"></i>加载中...';
            
            try {
                const response = await fetch(`${API_BASE_URL}/api/v1/models/load`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        model_name: modelName,
                        use_quantization: useQuantization.checked
                    })
                });
                
                const data = await response.json();
                
                if (response.ok && data.status === 'success') {
                    showStatus(`模型 ${modelName} 加载成功`, 'success');
                    
                    // 清空输入框
                    newModelName.value = '';
                    
                    // 刷新模型列表
                    loadModelList(true);
                } else {
                    showStatus('模型加载失败: ' + data.message, 'error');
                }
            } catch (error) {
                console.error('加载模型时出错:', error);
                showStatus('加载模型时发生错误: ' + error.message, 'error');
            } finally {
                // 恢复按钮状态
                loadNewModel.disabled = false;
                loadNewModel.innerHTML = '<i class="fa fa-download mr-1"></i>加载模型';
            }
        }
        
        // 卸载模型
        async function unloadModel(modelName) {
            try {
                const response = await fetch(`${API_BASE_URL}/api/v1/models/unload?model_name=${encodeURIComponent(modelName)}`, {
                    method: 'POST'
                });
                
                const data = await response.json();
                
                if (response.ok) {
                    showStatus(`模型 ${modelName} 卸载成功`, 'success');
                    
                    // 刷新模型列表
                    loadModelList(true);
                } else {
                    showStatus('模型卸载失败: ' + data.message, 'error');
                }
            } catch (error) {
                console.error('卸载模型时出错:', error);
                showStatus('卸载模型时发生错误', 'error');
            }
        }
        
        // 上传文档
        function handleUploadDocument() {
            // 创建一个隐藏的文件输入框
            const fileInput = document.createElement('input');
            fileInput.type = 'file';
            fileInput.accept = '.txt,.pdf,.docx,.md';
            fileInput.style.display = 'none';
            
            // 添加到文档
            document.body.appendChild(fileInput);
            
            // 触发文件选择
            fileInput.click();
            
            // 监听文件选择事件
            fileInput.addEventListener('change', async function() {
                if (this.files && this.files.length > 0) {
                    const file = this.files[0];
                    
                    // 创建FormData对象
                    const formData = new FormData();
                    formData.append('file', file);
                    
                    // 显示上传状态
                    showStatus(`正在上传文档: ${file.name}`, 'info');
                    
                    try {
                        const response = await fetch(`${API_BASE_URL}/api/v1/rag/upload`, {
                            method: 'POST',
                            body: formData
                        });
                        
                        const data = await response.json();
                        
                        if (response.ok && data.status === 'success') {
                            showStatus(`文档 ${file.name} 上传成功`, 'success');
                        } else {
                            showStatus('文档上传失败: ' + data.message, 'error');
                        }
                    } catch (error) {
                        console.error('上传文档时出错:', error);
                        showStatus('上传文档时发生错误', 'error');
                    }
                }
                
                // 移除文件输入框
                document.body.removeChild(this);
            });
        }
        
        // 页面加载完成后初始化
        document.addEventListener('DOMContentLoaded', init);
    </script>
</body>
</html>